package com.remote.common.model;

import io.netty.channel.ChannelHandlerContext;
import io.netty.util.Attribute;
import lombok.Getter;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static com.remote.common.constant.Constants.CLIENT_INFO;

public class ServerClientInfo {
    @Getter
    private ClientInfo clientInfo;
    /**
     * 控制端通道
     */
    @Getter
    private ChannelHandlerContext context;
    /**
     * 控制端信息
     */
    private Map<String, ClientInfo> controlClients;
    /**
     * 傀儡端信息
     */
    private Map<String, ClientInfo> puppetClients;
    /**
     * 控制端通道
     */
    private Map<String, ChannelHandlerContext> controlContexts;
    /**
     * 傀儡端通道
     */
    private Map<String, ChannelHandlerContext> puppetContexts;
    ;

    public ServerClientInfo(ClientInfo clientInfo, ChannelHandlerContext context) {
        this.clientInfo = clientInfo;
        this.controlClients = new ConcurrentHashMap<>();
        this.controlContexts = new ConcurrentHashMap<>();
        this.puppetClients = new ConcurrentHashMap<>();
        this.puppetContexts = new ConcurrentHashMap<>();
        this.context = context;
        Attribute<ServerClientInfo> clientInfoAttribute = context.channel().attr(CLIENT_INFO);
        clientInfoAttribute.set(this);
    }

    public Map<String, ClientInfo> controlClients() {
        return this.controlClients;
    }

    public Map<String, ClientInfo> puppetClients() {
        return this.puppetClients;
    }

    public Map<String, ChannelHandlerContext> controlContexts() {
        return this.controlContexts;
    }

    public Map<String, ChannelHandlerContext> puppetContexts() {
        return this.puppetContexts;
    }

    public void putControl(ClientInfo clientInfo, ChannelHandlerContext context) {
        this.controlClients.put(clientInfo.getClientId(), clientInfo);
        this.controlContexts.put(clientInfo.getClientId(), context);
    }

    public void removeControl(ClientInfo clientInfo) {
        this.controlClients.remove(clientInfo.getClientId());
        this.controlContexts.remove(clientInfo.getClientId());
    }

    public boolean containsControl(ClientInfo clientInfo) {
        return this.controlClients.containsKey(clientInfo.getClientId()) && this.controlContexts.containsKey(clientInfo.getClientId());
    }

    public ChannelHandlerContext getControlContext(String clientId) {
        return controlContexts.get(clientId);
    }

    public ClientInfo getControlClient(String clientId) {
        return controlClients.get(clientId);
    }

    public void putPuppet(ClientInfo clientInfo, ChannelHandlerContext context) {
        this.puppetClients.put(clientInfo.getClientId(), clientInfo);
        this.puppetContexts.put(clientInfo.getClientId(), context);
    }

    public boolean containsPuppet(ClientInfo clientInfo) {
        return this.puppetClients.containsKey(clientInfo.getClientId()) && this.puppetContexts.containsKey(clientInfo.getClientId());
    }


    public void removePuppet(ClientInfo clientInfo) {
        this.puppetClients.remove(clientInfo.getClientId());
        this.puppetContexts.remove(clientInfo.getClientId());
    }

    public ChannelHandlerContext getPuppetContext(String clientId) {
        return puppetContexts.get(clientId);
    }


    public ClientInfo getPuppetClient(String clientId) {
        return puppetClients.get(clientId);
    }


    public void update() {
        Attribute<ServerClientInfo> clientInfoAttribute = context.channel().attr(CLIENT_INFO);
        clientInfoAttribute.set(this);
    }


}
